package ru.niir.goodfil.ui;

import ru.niir.goodfil.db.ClientGroup;
import ru.niir.goodfil.exceptions.ValidationException;
import ru.niir.goodfil.exceptions.CreateFailureException;
import ru.niir.goodfil.exceptions.RemoveFailureException;
import ru.niir.goodfil.utils.validation.ValidationError;

import java.util.List;
import java.util.ArrayList;
import static org.apache.commons.lang.StringUtils.isEmpty;
import javax.faces.model.SelectItem;
import org.apache.log4j.Logger;
import ru.niir.goodfil.utils.validation.CreateCheckResult;
import ru.niir.goodfil.utils.validation.ValidationResult;

/**
 * Бин для работы с клиентскими групами.
 */
public class ClientGroupsBean extends PageBean
{

    private static final Logger logger = Logger.getLogger(ClientGroupsBean.class);

    /** Идентификатор клиентской группы */
    private long clientGroupId;
    /** Наименование клиентской группы */
    private String clientGroupName;
    /** Сумма */
    private String clientGroupSum;
    /** Клиентская группа активна */
    private boolean clientGroupActive;

    /**
     * Возвращает идентификатор клиентской группы.
     * @return идентификатор
     */
    public long getClientGroupId() {
        return clientGroupId;
    }

    /**
     * Устанавливает идентификатор клиентской группы.
     * @param clientGroupId идентификатор
     */
    public void setClientGroupId(long clientGroupId) {
        this.clientGroupId = clientGroupId;
    }

    /**
     * Возвращает наименование клиентской группы.
     * @return наименование
     */
    public String getClientGroupName() {
        return clientGroupName;
    }

    /**
     * Устанавливает наименование клиентской группы.
     * @param clientGroupName наименование
     */
    public void setClientGroupName(String clientGroupName) {
        this.clientGroupName = clientGroupName;
    }

    /**
     * Возвращает сумму.
     * @return сумма
     */
    public String getClientGroupSum() {
        return clientGroupSum;
    }

    /**
     * Устанавливает сумму.
     * @param clientGroupSum сумма
     */
    public void setClientGroupSum(String clientGroupSum) {
        this.clientGroupSum = clientGroupSum;
    }

    /**
     * Возвращает активность клиентской группы.
     * @return <b>true</b>-активна</br>
     * <b>false</b>-не активна
     */
    public boolean isClientGroupActive() {
        return clientGroupActive;
    }

    /**
     * Устанавливает активность клиентской группы.
     * @param clientGroupActive <b>true</b>-активна</br>
     * <b>false</b>-не активна
     */
    public void setClientGroupActive(boolean clientGroupActive) {
        this.clientGroupActive = clientGroupActive;
    }

    /**
     * Возвращает список клиентских групп.
     * @return список
     */
    public List<ClientGroup> getClientGroups()
    {
        return gf().getClientGroups();
    }

    /**
     * Возвращает перечень клиентских групп.
     * @return печень
     */
    public List<SelectItem> getClientGroupsAsSelectItems() {
        List<SelectItem> result = new ArrayList<SelectItem>();
        List<ClientGroup> clientGroups = gf().getClientGroups();
        for (ClientGroup clientGroup : clientGroups)
            result.add(new SelectItem(clientGroup.getId(), clientGroup.getName()));
        return result;
    }

    /**
     * Возвращает
     * @return
     */
    public List<SelectItem> getClientGroupsWithEmptyAsSelectItems() {
        List<SelectItem> result = getClientGroupsAsSelectItems();
        result.add(0, new SelectItem(-1, "Не важно"));
        return result;
    }

    /**
     * -------------------------------------------------------------------------
     * ----------Работа с БД----------
     * -------------------------------------------------------------------------
     */

    /**
     * Создать клиентскую группу
     */
    public void addClientGroup() {
        validateClientGroup();
        if (!isValOk()) return;

        ClientGroup clientGroup = new ClientGroup();
        clientGroup.setName(clientGroupName);
//        clientGroup.setActive(clientGroupActive);
        clientGroup.setCriteriaSum(Float.parseFloat(clientGroupSum));

        try
        {
            gf().saveClientGroup(clientGroup);
            validated(null);
        }
        catch (ValidationException ex)
        {
            logger.error(ex);
            ex.printStackTrace();
            ValidationResult validationResult = ex.getResult();
            for (ValidationError error : validationResult.getErrors())
                validated(error.toHumanString());
        }
        catch (CreateFailureException ex)
        {
            logger.error(ex);
            ex.printStackTrace();
            CreateCheckResult createCheckResult = ex.getResult();
            validated(createCheckResult.getMsg());
        }
    }

    /**
     * Обновить информацию о клиентской группе
     */
    public void saveClientGroup() {
        validateClientGroup();
        if (!isValOk()) return;

        ClientGroup clientGroup = gf().getClientGroupById(clientGroupId);
        clientGroup.setName(clientGroupName);
        clientGroup.setCriteriaSum(Float.parseFloat(clientGroupSum));
//        clientGroup.setActive(clientGroupActive);

        try {
            gf().updateClientGroup(clientGroup);
            validated(null);
        } catch (ValidationException ex) {
            logger.error(ex);
            ex.printStackTrace();
            ValidationResult validationResult = ex.getResult();
            for (ValidationError error : validationResult.getErrors())
                validated(error.toHumanString());
        }
    }

    /**
     * Удалить клиентскую группу
     */
    public void removeClientGroup() {

        if (gf().removeCheckClientGroup(clientGroupId).isOk())
        {
            try
            {
                gf().removeClientGroup(clientGroupId);
                validated(null);
            }
            catch (RemoveFailureException ex)
            {
                logger.error(ex);
                ex.printStackTrace();
                String[] objs = ex.getRemoveCheckResult().getLinkedObjects();
                for (String obj : objs) {
                    validated("Клиентскую группу нельзя удалить, т.к. он связан с другими объектами.");
                    break;
                }
            }
        } 
        else
        {
            validated("Невозможно удалить клиентскую группу, т.к. она содержит клиентов");
        }
    }

    /**
     * -------------------------------------------------------------------------
     * ----------Валидация----------
     * -------------------------------------------------------------------------
     */

    /**
     * Проверить параметры клиентской группы
     */
    public void validateClientGroup() {
        //  Проверка на то, что наименование клиентской группы заолнено
        if (isEmpty(clientGroupName)) validated("Наименование клиентской группы должно быть заполнено");

        //  Проверка имени клиентской группы на уникальность
        for (ClientGroup clientGroup : getClientGroups())
            if (clientGroup.getName().trim().toLowerCase().equals(clientGroupName.trim().toLowerCase()) && clientGroup.getId() != clientGroupId)
                validated("Клиентская группа с таким именем уже существует");

        //  Проверка на то, что сумма - число
        try {
            float sum = Float.parseFloat(clientGroupSum);
            if (sum < 0) validated("Сумма должна быть положительным числом");
        } catch (NumberFormatException nfe) {
            validated("Мин. сумма закупок должна быть числом");
        }


    }
}
